home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_200 / 208_01 / e2.c < prev    next >
Text File  |  1987-10-11  |  9KB  |  396 lines

  1. /*
  2. HEADER:        CUG208;
  3. TITLE:        'e' for CP/M68K
  4. VERSION:    1.48+
  5.  
  6. DESCRIPTION:    "a screen editor";
  7.  
  8. KEYWORDS:    editor;
  9. SYSTEM:        CP/M68K, V1.2;
  10. FILENAME:    e/e2.c
  11. WARNINGS:    "the default value is for systems with 128K bytes
  12.          of memory or more";
  13. SEE-ALSO:    cpm68k.c, e68k.doc, CUG VOL 133;
  14. AUTHORS:    G.N.Gilbert('e'), J.W.Haefner(for DeSmet C on MSDOS and UNIX)
  15. CODER:        Yoshimasa Tsuji
  16. COMPILERS:    DRI C(Alcyon C) for CP/M68K;
  17. */
  18. /*
  19.     FUNCTIONS: movechar,moveline, movepage, moveword, insertchar,
  20.             deletechar,crdelete,deleteword,crinsert,adjustc,
  21.             sync, pointtobrack.
  22.     PURPOSE: perform text changing commands
  23. */
  24.  
  25. # include "e.h"
  26.  
  27. movechar(move)    /*move cursor by 'move' columns to the right
  28.           return YES unless going off text*/
  29. int move;
  30. {
  31.     int cp, len, result;
  32.  
  33.     cp=charn+move;
  34.     result=YES;
  35.     if (cp < 0) {
  36.         result=moveline(-1);
  37.  
  38.         if (result) {
  39.             adjustc(LLIM);
  40.             movechar(cp+1);
  41.         }
  42.         else sync(0);
  43.     }
  44.     else if (cp > (len=strlen(text))) {
  45.         result=moveline(1);
  46.         if (result) {
  47.             sync(0);
  48.             movechar(cp-len-1);
  49.         }
  50.         else adjustc(LLIM);
  51.     }
  52.     else sync(cp);
  53.     return(result);
  54. }
  55.  
  56. moveline(move)    /*move cursor by 'move' lines down
  57.          return YES if Ok, NO if going off text*/
  58. register int move;
  59. {
  60.     register int line;
  61.  
  62.     puttext();
  63.     if ( (move<0?-move:move) > SHEIGHT) gotoxy(WAITPOS,0);
  64.     line=cline;
  65.     if ((cline=loc(cline,move)) != line) {
  66.         strcpy(text,getline(cline));
  67.         if (cline < pfirst || cline > plast) {
  68.             if (move == 1 || move == -1) scroll(move);
  69.             else putpage();
  70.         }
  71.         else {
  72.             if (hilight) putline(line,cursory);
  73.             cursory+=cline-line;
  74.             adjustc(cursorx);
  75.             if (hilight) putline(cline,cursory);
  76.         }
  77.         return(YES);
  78.     }
  79.     else return(NO);
  80. }
  81.  
  82. scroll(move)    /*scroll up (move==1) or down 1 line*/
  83. int move;
  84. {
  85.     if (move == 1) {
  86.         linedelete(topline);
  87.         putline(cline-1,SHEIGHT-1);
  88.     }
  89.     else {
  90.         insertline();
  91.         putline(cline+1,topline+1);
  92.     }
  93.     adjustc(cursorx);
  94.     putline(cline,cursory);
  95.     if (plast-pfirst == (SHEIGHT-topline)) plast+=move;
  96.     pfirst+=move;
  97. }
  98.  
  99. jumpline(move)    /*move current line by move lines down, checking for
  100.             interrupt from user (if interrupted, do nothing,
  101.             and return NO) */
  102. int move;
  103. {
  104.     register int line, dest;
  105.  
  106.     puttext();
  107.     dest=cline+move;
  108.     dest-=dest%100;
  109.     if (dest > lastread) {
  110.         gotoxy(WAITPOS,0);
  111.         line=cline;
  112.         while (line < dest && loc(line,100) != line) {
  113.             line+=100;
  114.             if (testkey() == ESCKEY) {
  115.                 error("Interrupted");
  116.                 return(NO);
  117.             }
  118.         }
  119.     }
  120.     moveline(move);
  121.     return(YES);
  122. }
  123.  
  124. movepage(dir)    /*move current line by a page down (dir==0) or up (-1)*/
  125. int dir;
  126. {
  127.     int move, line;
  128.  
  129.     puttext();
  130.     move=(SHEIGHT-topline)/2 - PAGEOVERLAP;
  131.     if (dir) move=pfirst-cline-move;
  132.     else move=plast-cline+move;
  133.     line = cline;
  134.     if ( (cline=loc(cline,move)) != line) {
  135.         strcpy(text,getline(cline));
  136.         putpage();
  137.     }
  138. }
  139.  
  140. moveword(move)    /*move 1 word to the right (move -ve: left)*/
  141. int move;
  142. {
  143.     if (charn+move < 0) {
  144.         moveline(-1);
  145.         charn=strlen(text);
  146.     }
  147.     else if (charn+move >= strlen(text)) {
  148.         moveline(1);
  149.         sync(0);
  150.         if (inword(text[0])) return;
  151.     }
  152.  
  153.     while ((move<0 || text[charn]) && inword(text[charn]) && (charn+=move));
  154.     while ((move<0 || text[charn]) && !inword(text[charn]) && (charn+=move));
  155.     if (move < 0 && charn) {
  156.         while(inword(text[charn]) && --charn);
  157.         if (charn || !inword(text[charn]) ) charn++;
  158.     }
  159.     sync(charn);
  160. }
  161.  
  162. insertchar(c)    /*inserts 'c' at charn, moves cursor up  one */
  163. char c;
  164. {
  165.     int cp;
  166.  
  167.     if ( (cp=strlen(text)+1) >= (LLIM-1))
  168.         error("Line too long");
  169.     else {
  170.         for (; cp >= charn; cp--) text[cp+1]=text[cp];
  171.         text[charn]=c;
  172.         altered=YES;
  173.         rewrite(charn,cursorx);
  174.         if (c == ')' || c == '}' || c == ']') pointtobrack(c);
  175.         sync(charn+1);
  176.     }
  177. }
  178.  
  179. pointtobrack(closebr)    /*momentarily put cursor on matching opening
  180.             bracket */
  181. char closebr;
  182. {
  183.     int chn, chna, i, l, brackline, brackcount, cx, openbr, c;
  184.     char *t;
  185.  
  186.     if (closebr == ')') openbr='(';
  187.     else if (closebr == '}') openbr='{';
  188.     else openbr='[';
  189.  
  190.     for (chn=charn, t=text, l=cline, brackcount=0, brackline=cursory;
  191.         l >= pfirst; brackline--) {
  192.             for (; chn >= 0; chn--) {
  193.             if ((c= *(t+chn)) == closebr) brackcount++;
  194.             if (c == openbr) brackcount--;
  195.             if (brackcount == 0) {
  196.                 for (chna=0, cx=0; chna < chn; chna++, cx++)
  197.                     if (*(t+chna) == '\t') cx+= tabwidth-1-(cx%tabwidth);
  198.                 if (l == cline || blockscroll) cx+= (lastoff>0)-lastoff;
  199.                 if (cx < 0|| cx >= SWIDTH) return;
  200.                 gotoxy(cx,brackline);
  201.                 for (i=0; i < (8 * CURSORWAIT); i++);
  202.                 return;
  203.             }
  204.         }
  205.         chn=strlen( (t=getline(--l) ))-1;
  206.     }
  207. }
  208.  
  209. deletechar(dir)    /*deletes char before (dir= -1) or at (dir=0) cursor */
  210. {
  211.     register int cp;
  212.  
  213.     cp=charn+dir;
  214.     if (cp < 0) {
  215.         if (cline > 1) crdelete(-1);
  216.     }
  217.     else if (text[cp] == '\0') {
  218.         if (cline < lastl) crdelete(0);
  219.     }
  220.     else {
  221.         while(text[cp]=text[cp+1])
  222.             cp++;
  223.         altered=YES;
  224.         sync(charn+dir);
  225.         if (calcoffset() != lastoff)rewrite(0,0);
  226.         else rewrite(charn,cursorx);
  227.     }
  228. }
  229.  
  230. crdelete(dir)    /*delete a [CR] before (dir== -1)or at (dir==0) cursor */
  231. int dir;
  232. {
  233.     int delline, len;
  234.     char textb[LLIM];
  235.  
  236.     altered=YES;
  237.     if (dir == 0) {
  238.         delline=cline+1;
  239.         strcpy(textb,getline(delline));
  240.         cursory++;
  241.     }
  242.     else {
  243.         delline=cline;
  244.         strcpy(textb,text);
  245.         if (cline > 1)
  246.             strcpy(text,getline(--cline));
  247.         else puttext();
  248.     }
  249.     sync(len=strlen(text));
  250.     if (len+strlen(textb) >= LLIM) {
  251.         textb[LLIM-len]='\0';
  252.         error("Line too long - cut short");
  253.     }
  254.     strcat(text,textb);
  255.     puttext();
  256.     delete(delline);
  257.     if (delline > plast || delline <= pfirst) putpage();
  258.     else {
  259.         linedelete(cursory--);
  260.         rewrite(0,0);
  261.         if (plast <= lastl && lastl-pfirst > SHEIGHT - topline)
  262.             putline(plast, SHEIGHT);
  263.         else plast=lastl;
  264.     }
  265. }
  266.  
  267. deleteword()    /*delete rest of word if in word, else up to next word */
  268. {
  269.     int pend, cp, in, c;
  270.  
  271.     for (in=inword(text[pend=charn]);
  272.         (c=text[pend]) && (in ? inword(c): !inword(c)); pend++);
  273.         for (cp=charn; (text[cp]=text[pend]); pend++, cp++);
  274.     rewrite(charn,cursorx);
  275.     altered=YES;
  276. }
  277.  
  278. crinsert(dir)   /*insert a [CR] behind (dir==0) or in front of (-1) cursor*/
  279. {
  280.     char textb[LLIM], c;
  281.     int charnb = 0;
  282.  
  283.     if (autoin && !isspace(text[charn]))
  284.         while(isspace(c=text[charnb]) ) textb[charnb++]=c;
  285.     strcpy(&textb[charnb],&text[charn]);
  286.     text[charn]='\0';
  287.     altered=YES;
  288.     /* begin Haefner code */
  289.     if (dir == 0) puttext();
  290.     if ((cline=inject(cline,textb)+dir) == FAIL) return;
  291.     if (dir == 0) {
  292.         strcpy(text,getline(cline));
  293.         sync(charnb);
  294.     }
  295.     /* end Haefner code */
  296.     /*
  297.         if (dir == 0) {
  298.             puttext();
  299.             strcpy(text,textb);
  300.             altered=YES;
  301.             sync(charnb);
  302.             if ((cline=inject(cline,textb)) == FAIL) return;
  303.             }
  304.         else if (inject(cline,textb) == FAIL) return;
  305.     */
  306.     if (cursory >= SHEIGHT) {
  307.         puttext();
  308.         putpage();
  309.     }
  310.     else {
  311.         /* haefner code */
  312.         gotoxy(0,cursory+1);
  313.         /* haefner code */
  314.         insertline();
  315.         if (dir == 0) putline(cline-1,cursory++);
  316.         else putline(cline+1,cursory+1);
  317.         if (plast-pfirst < SHEIGHT-topline)plast++;
  318.         rewrite(0,0);
  319.         /*
  320.                         rewrite(0,0);
  321.                         if (plast-pfirst < SHEIGHT-topline)plast++;
  322.         */
  323.     }
  324. }
  325.  
  326. undo()    /*undoes edits on current line and then from history*/
  327. {
  328.  
  329.     struct histstep *step;
  330.     short onpage;
  331.     int l, slot;
  332.     char textb[LLIM];
  333.  
  334.     if (altered) {
  335.         if (cline <= lastl) strcpy(text,getline(cline));
  336.         else text[0]='\0';
  337.         altered=NO;
  338.         adjustc(cursorx);
  339.         rewrite(0,0);
  340.     }
  341.     else {
  342.         if (histcnt == 0) {
  343.             error("Nothing to undo");
  344.             return;
  345.         }
  346.         onpage=NO;
  347.         do {
  348.             if (--histptr < 0) histptr= (HISTLEN-1);
  349.             histcnt--;
  350.             step= &history[histptr];
  351.             l=step->histline;
  352.             onpage= onpage || (l >= pfirst && l <= plast);
  353.             storehist=NO;
  354.             switch (step->histtype) {
  355.             case HISTINSERT:
  356.                 delete(l+1);
  357.                 break;
  358.             case HISTDELETE:
  359.                 if ((slot=pageloc[step->histp.page]) <= 0)
  360.                     slot=swappin(step->histp.page);
  361.                 strcpy(textb,slotaddr[slot] + step->histp.moffset);
  362.                 inject(l-1,textb);
  363.                 break;
  364.             case HISTREPLACE:
  365.                 tp[l].page=step->histp.page;
  366.                 tp[l].moffset=step->histp.mof